package com.spz.demo.singleboot.aop;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import java.util.List;

/**
 * Controller 层参数校验
 * 配合Hibernate实体类参数校验
 *
 * @author spz
 */
@Slf4j
@Component
@Aspect
@Order(3)
public class BindingResultAop {

    /**
     * 设置切入点为 controller 层
     */
    @Pointcut("execution(* com.spz.demo.singleboot.controller..*.*(..))")
    public void aopMethod(){}

    /**
     * 检查 Controller 方法的参数是否合法
     * @param joinPoint
     * @return
     * @throws Throwable
     */
    @Around("aopMethod()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable{
        BindingResult bindingResult = null;
        for(Object arg:joinPoint.getArgs()){//遍历被通知方法的参数列表
            if(arg instanceof BindingResult){
                bindingResult = (BindingResult) arg;
            }
        }
        if(bindingResult != null){
            if(bindingResult.hasErrors()){
                String errorInfo = "";
                List<FieldError> errors = bindingResult.getFieldErrors();//获取字段参数不合法的错误集合
                for(FieldError error : errors){
                    errorInfo = errorInfo + "[" + error.getField() + " " + error.getDefaultMessage() + "]";
                }
                throw new Throwable("参数校验异常：" + errorInfo);
            }
        }
        return joinPoint.proceed();//执行目标方法
    }
}
